package thirdweek;

import secondweek.EmptyCollectionException;
import secondweek.LinearNode;

/**
 * LinkedQueue represents a linked implementation of a queue.
 *
 * @author Lewis and Chase
 * @version 4.0
 */
public class LinkedQueue<T> implements QueueADT<T> {
    public int count;
    private LinearNode<T> head, tail;
    /**
     * Creates an empty queue.
     */
    public LinkedQueue(){
        count = 0;
        head = tail = null;
    }
    /**
     * Adds the specified element to the tail of this queue.
     * @param element the element to be added to the tail of this queue
     */
    @Override
    public void enqueue(T element) {
        LinearNode<T> node = new LinearNode<T>(element);
        if(isEmpty())
            head = node;
        else
            tail.setNext(node);
        tail = node;
        count++;
    }
    /**
     * Remove the element at the front of this queue and return a reference to it. Throws an EmptyCollectionException if the queue is empty.
     */
    @Override
    public T dequeue() throws EnumConstantNotPresentException{
        if (isEmpty())
            throw new EmptyCollectionException("queue");

        T result = head.getElement();
        head = head.getNext();
        count--;

        if(isEmpty())
            tail = null;
        return result;
    }
    @Override
    public T first() {
        if (isEmpty())
            throw new EmptyCollectionException("queue");
        else
            return head.getElement();
    }

    @Override
    public boolean isEmpty() {
        if(count == 0 )
            return true;
        else
            return false;
    }

    @Override
    public int size() {
        return count;
    }
    @Override
    public String toString() {
        LinearNode<T> temp = head;
        String result = "";
        while(temp != null)
        {
            result += temp.getElement().toString() + " ";
            temp = temp.getNext();
        }
        return result;
    }
}
